/** 
 * 全局滤镜效果管理
 * Author      : wyang
 * Create Time : 2016.11.04
 */
module.exports = cc.Class({
    extends: cc.Object,

    ctor : function () {
        this._vsh = "attribute vec4 a_position;"                        
                    + "attribute vec2 a_texCoord;"
                    + "attribute vec4 a_color;"  
                    + "varying vec4 v_fragmentColor;"
                    + "varying vec2 v_texCoord;"
                    + "void main()"
                    + "{"
                    + "  gl_Position = CC_PMatrix * a_position;"
                    + "  v_fragmentColor = a_color;"
                    + "  v_texCoord = a_texCoord;" 
                    + "}";

        this._fsh = "varying vec4 v_fragmentColor;"                                                                        
                    + "varying vec2 v_texCoord;"
                    + "void main()"
                    + "{" 
                    + "  vec4 col = texture2D(CC_Texture0, v_texCoord);"
                    + "  float grey = dot(col.rgb, vec3(0.299*0.75, 0.587*0.75, 0.114*0.75));"
                    + "  gl_FragColor = vec4(grey, grey, grey, col.a);"
                    + "}";

        this._normalFsh = "varying vec4 v_fragmentColor;"                                                                
                    + "varying vec2 v_texCoord;"
                    + "void main()"
                    + "{" 
                    + "  gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);"
                    + "}";

        this.greyShader = null;
        this.normalShade = null;

        this.init();
    },

    init: function(){
        if( !('opengl' in cc.sys.capabilities)){
            return;
        }

        if(!this.greyShader){
            this.greyShader = this.createShader(this._vsh,this._fsh);
            this.greyShader.retain();
        }

        if(!this.normalShade){
            this.normalShade = this.createShader(this._vsh,this._normalFsh);
            this.normalShade.retain();
        }
    },

    createShader: function(vsh,fsh){
        var shader;
        if(cc.sys.isNative){
            shader = new cc.GLProgram();
            shader.initWithString(vsh,fsh);
            shader.link();
            shader.updateUniforms();
        }
        else{
            shader = new cc.GLProgram();
            shader.initWithVertexShaderByteArray(vsh,fsh);

            shader.addAttribute(cc.macro.ATTRIBUTE_NAME_POSITION, cc.macro.VERTEX_ATTRIB_POSITION);  
            shader.addAttribute(cc.macro.ATTRIBUTE_NAME_COLOR, cc.macro.VERTEX_ATTRIB_COLOR);  
            shader.addAttribute(cc.macro.ATTRIBUTE_NAME_TEX_COORD, cc.macro.VERTEX_ATTRIB_TEX_COORDS); 

            shader.link();
            shader.updateUniforms();
        }
        return shader;
    },

    makeGrey: function(node){
        if (!node) {
            cc.warn('node is null.');
            return;
        }
        if( 'opengl' in cc.sys.capabilities ) {
            this.setProgram(node._sgNode,this.greyShader);
        }
    },

    restore: function(node){
        if (!node) {
            cc.warn('node is null.');
            return;
        }
        if ('opengl' in cc.sys.capabilities ) {
            this.setProgram(node._sgNode,this.normalShade);
        }
    },

    setProgram: function(node, program){
        if (cc.sys.isNative) {  
            var glProgram_state = cc.GLProgramState.getOrCreateWithGLProgram(program);  
            node.setGLProgramState(glProgram_state);  
        } else {  
            node.setShaderProgram(program);
        }  
    
        var children = node.children;  
        if (!children) return;  
    
        for (var i = 0; i < children.length; i++) {  
            this.setProgram(children[i], program);
        }
    },
});